<template>
 <div class='player' v-show="playList.length > 0">
   <!--标准模式 添加一个动画效果 动画效果使用钩子函数进行改造-->
   <transition name="normal" @enter="enter" @after-enter ="afterEnter" 
                             @leave="leave" @after-leave ="afterLeave">
   <div class="normal-player" v-show="fullScreen">
      <!--背景图 -->
      <div class="background">
        <img  width="100%" height="100%" :src="currentSong.image"/>
      </div>
      <!--顶部层 -->
      <div class="top">
        <div class="back" @click="back">
          <i class="icon-back"></i>
        </div>
        <!--v-html标题含有转义字符 -->
        <h1 class="title" v-html="currentSong.name"></h1>
        <h2 class="subtitle" v-html="currentSong.singer"></h2>
      </div>
      <!--中间层 -->
      <div class="middle">
        <div class="middle-l">
          <!--唱片展示区 -->
          <div class="cd-wrapper" ref="cdWrapper">
            <!--cdClass唱片旋转效果样式 -->
            <div class="cd" :class="cdClass">
              <img class="image" :src="currentSong.image" />
            </div>
          </div>
        </div>
      </div>
      <!--底部层 -->
      <div class="bottom">
        <!--播放进度条 -->
        <div class="progress-wrapper"></div>
        <!--按钮操作区 -->
        <div class="operators">
          <!--播放模式: 顺序 or 随机 or 单曲  -->
          <div class="icon i-left">
            <i class="icon-sequence"></i>
          </div>
          <!--上一首 -->
          <div class="icon i-left">
            <i class="icon-prev"></i>
          </div>
          <!--开始 or 暂停 -->
          <div class="icon i-center">
            <!-- <i class="icon-play"  @click="togglePlaying"></i> -->
            <!--playicon计算属性 修改播放图标的状态 -->
            <i :class="playicon" @click="togglePlaying"></i>
          </div>
          <!--下一首 -->
          <div class="icon i-right">
            <i class="icon-next"></i>
          </div>
          <!--收藏 -->
          <div class="icon i-right">
            <i class="dicon-not-favorite"></i>
          </div>
        </div>
      </div>
   </div>
   </transition>
   <!--迷你模式 -->
   <transition name="mini">
   <div class='mini-player' v-show="!fullScreen" @click="open">
     <div class="icon">
        <img :class="cdClass"  width="40" height="40" :src="currentSong.image"/>
     </div>
     <div class="text">
       <h2 class="name" v-html="currentSong.name"></h2>
       <p class="desc" v-html="currentSong.singer"></p>
     </div>
     <!--播放 -->
     <div class="control">
       <i @click.stop="togglePlaying" class="icon-mini" :class="miniIcon"></i>
     </div>
     <div class="control">
        <i class="icon-playlist"></i>
     </div>
   </div>
   </transition>
   <!--播放 并且:src嵌入的音频的URL。 该URL应遵从 HTTP access controls. 这是一个可选属性；你可以在audio元素中使用 元素来替代该属性指定嵌入的音频-->
   <!-- <audio  id="audio" ref="audio" :src="currentSong.url"></audio> -->
   <audio id="audio" ref="audio">
     <source :src="currentSong.url"/>
   </audio>
 </div>
</template>

<script>
import {mapGetters,mapMutations} from 'vuex';
import animations from 'create-keyframe-animation';

export default {
  created() {
    console.log('player组件定为全局组件');
  },
  computed: {
    ...mapGetters([
     'fullScreen', // 判断标准 or 缩小
     'playList',
     'currentSong', // 当前的歌曲 已经存储在state中,所以进行初始化
     'playing' // getters.js文件中获取
    ]),
  
    //更改标准模式播放的图标
    playicon() {
      return this.playing? 'icon-pause' : 'icon-play';
    },

    //更改迷你模式的播放状态的图标
    miniIcon() {
      return this.playing ? 'icon-pause-mini' : 'icon-play-mini';
    },
    cdClass() {
      return this.playing ? 'play' : 'play pause';
    }
  },
  data() {
    return {};
  },
  methods: {
    // 返回
    back() {
      this.setFullScreen(false);// 修改mutations中的值
    },

    // 标准模式 与迷你模式进行切换
    open() {
      this.setFullScreen(true);
    },

    //动画钩子函数enter(),leave(),afterEnter(),leaveEnter(),el表示dom元素 ,done表示回调函数调到下个钩子函数
    enter(el, done) {
      const {x, y, scale} = this._getPosAndScale();
      console.log('动画钩子函数执行的enter方法',{x,y,scale});
      //定义动画
      let animation = {
        0: {
          transform: `translate3d(${x}px,${y}px,0) scale(${scale})`
        },
        60: {
          transform: `translate3d(0,0,0) scale(1.1)` // 放大
        },
        100: {
          transform: `translate3d(0,0,0) scale(1)` // 回复原来大小
        }
      }

      // //注册animations动画
      animations.registerAnimation({
          name: 'move',
          animation,
          presets: {
            duration: 400,
            easing: 'linear'
          }
        })

      // 执行animations动画，动画的dom位置cdWrapper,done表示执行afterEnter()
      animations.runAnimation(this.$refs.cdWrapper, 'move', done)
    },
    afterEnter(){
      console.log('执行afterEnter方法');
      animations.unregisterAnimation('move');
      //将animation动画设置为'';
      this.$refs.cdWrapper.style.animation = '';
    },
    leave(el, done){
      console.log('动画钩子函数执行的leave方法');
      this.$refs.cdWrapper.style.animation = 'all 0.4s';
      const {x, y, scale} = this._getPosAndScale(); // 获取目标的位置
      this.$refs.cdWrapper.style['transform'] = `translate3d(${x}px,${y}px,0) scale(${scale})`;
      // 触发监听事件---原来需要延迟一下
      const timer = setTimeout(done, 400)
      this.$refs.cdWrapper.addEventListener('transitionend', () => {
        clearTimeout(timer)
        done()
      });
      //this.$refs.cdWrapper.addEventListener('transitionend',done);
    },
    afterLeave(){
      console.log('执行afterLeave方法');
      this.$refs.cdWrapper.style.transition = ''
      this.$refs.cdWrapper.style['transform'] = ''
    },

    // 播放 or 暂停音乐
    togglePlaying() {
      console.log('触发togglePlaying切换播放状态......');
      this.setPlayingState(!this.playing);
    },

    //获取迷你模式调到标准模式的位置
    _getPosAndScale(){
      const targetWidth = 40;
      const paddingLeft = 40; //迷你模式的背景图左侧
      const paddingBottom = 30; // 迷你模式的底部
      const paddingTop = 80; // 标准模式的顶部
      const width = window.innerWidth * 0.8;//标准模式的圆形
      const scale = targetWidth / width // 缩放比例
      const x = -(window.innerHeight / 2 - paddingLeft);//x轴方向偏移的位置 以中心为原坐标
      const y = window.innerHeight - paddingTop - width/2 - paddingBottom;
      return {x, y, scale};
    },
    
    ...mapMutations({
      setFullScreen: 'SET_FULL_SCREEN',
      setPlayingState: 'SET_PLAYING_STATE' //修改播放状态
    })
  },
  watch: {
    //改变currentSong的值
    currentSong() {
      console.log('监听currentSong数据的变化触发');
      this.$nextTick(() => {
        this.$refs.audio.play(); //  DOMException: The play() request was interrupted by a new load request
      })
    },

    //播放器控制状态
    playing(newPlaying) {
      console.log('watch监听到播放器状态的改变....');
      const audio = this.$refs.audio;
      this.$nextTick(() => {
        var lastRunTime = Date.now();
        var currentTime = Date.now();
        var protectTime = 100;//设置保护性延时 单位毫秒，不要小于50 建议100以上
        if((currentTime - lastRunTime) < protectTime){
          return;//两次执行太过频繁，直接退出
        }
        if(newPlaying){
          audio.play();
        }else{
          audio.pause();
        }
          newPlaying != newPlaying;
          lastRunTime=Date.now();
      })
    }
  }
}
</script>

<style lang="scss" rel="stylesheet/scss">
  @import "@/assets/style/mixin.scss";
.player {
  .normal-player {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 150;
    background: #fff;
    &.normal-enter-active,&.normal-leave-active {
      transition:all 0.4s; 
      .top,.bottom {
        transition: all 0.4s cubic-bezier(0.86, 0.18, 0.82, 1.32);
      }
    }
    // 如将opacity设置为0，enter是进入的动画过程函数,leave对应的是消失的过程函数
    &.normal-enter,&.normal-leave-to{ // 前后enter,leave位置不可错位
      opacity: 0;
      .top {
        transform: translate3d(0,-100px,0);
      }
      .bottom {
        transform: translate3d(0,100px,0);
      }
    }
    .background { // 背景图的样式
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100;
      z-index: 40;
      opacity: 0.6; //透明度
      filter: blur(20px);
    }
    .top { // 顶部层
      position: relative;
      margin-bottom: 25px;
      .back {
        position: absolute;// 返回
        top: o;
        left: 6px;
        z-index: 60;
        .icon-back {
          display: block;
          padding: 9px;
          color: #f01414;
          font-size: 14px;
        }
      }
      .title {
          width: 80%;
          margin: 0 auto;
          line-height: 40px;
          text-align: center;
          color: rgb(0, 0, 0);
          font-size: 14px;
          font-weight: 500;
      }
      .subtitle {
          line-height: 20px;
          text-align: center;
          color: #233434;
          font-size: 12px;
      }
    }
    .middle { // 中间层
        position:fixed;
        top:88px;
        left: 0;
        width: 100%;
        bottom: 170px;
        white-space:nowrap;
        font-size: 0;
        .middle-l {
          position: relative;
          display: inline-block;
          vertical-align: top;
          width: 100%;
          height: 0;
          padding-top: 80%;// 图片自适应,设置高度0，padding-top
          .cd-wrapper { // 唱片内容
            position: absolute;
            top: 0;
            left: 10%;
            width: 80%;
            height: 100%;
            .cd { // 唱片图片
              width: 100%;
              height: 100%;
              box-sizing: border-box;
              border: 1px solid rgba(255, 255, 255, 0.1);
              border-radius: 50%; // 绘制一个圆形图
              &.play { // 唱片旋转效果
                animation: rotate 10s linear infinite;
              }
              &.pause {
                animation-play-state: paused
              }
              .image {
                position: absolute;
                width: 100%;
                height: 100%;
                border-radius: 50%;
                left: 0;
                top: 0;
              }
            }
          }
        }
    }
    .bottom { // 底部层
        position: absolute;
        bottom: 50px;
        width: 100%;
        .progress-wrapper {
          display: flex; // 弹性布局
          width: 80%;
          margin: 0 auto;
          padding: 10px 0;
          align-items: center;
        }
        .operators { //按钮操作
          display: flex;
          align-items: center;
          .icon {
            flex: 1;
            color: #f80000;
            font-size: 30px;
          }
           .i-left {
             text-align: right
            }
            .i-center {
             padding: 0 20px;
             text-align: center;
            }
            i {
             font-size: 20px;
            }
           .i-right {
             text-align: left;
           }
           .icon-favorite {
            color: #f80000;
           }
        }
    }
  }
  .mini-player {
   display: flex;
   align-items: center;
   position: fixed;
   left: 0;
   bottom: 0;
   width: 100%;
   z-index: 180;
   height: 60px;
   background: rgb(148, 158, 167);
   &.mini-enter-active,&.mini-leave-active {
     transition: all 0.4s;
   }
   &.mini-enter,&.mini-leave-to {
     opacity: 0;
   }
   .icon {
     flex: 0 0 40px; //由于父类是flex布局
     width: 40px;
     padding: 0 10px 0 20px;
     img {
      border-radius: 50%;
      &.play {
        animation: rotate 10s linear infinite;
      }
      &.pause {
        animation-play-state: paused
      }
     }
   }
   .text {
     display: flex;// 文字flex布局
     flex-direction: column; // 子元素在父容器中的位置。column：纵向排列
     justify-content: center; // 弹性盒子元素在主轴（横轴）方向上的对齐方式
     flex: 1;
     line-height: 20px;
     overflow: hidden;//超出父类会截取隐藏
     .name {
      margin-bottom: 2px;
      white-space: nowrap; //是否换行，不换行，单行
      font-size: 14px;
      color: #000;
     }
     .desc {
       font-size: 12px;
       white-space: nowrap; //是否换行，不换行，单行
       color: #233434;
     }
   }
   .control{
      flex: 0 0 30px;
      width: 30px;
      padding: 0 10px;
      .icon-play-mini, .icon-pause-mini, .icon-playlist {
        font-size: 20px;
        color: #f80000;
      }
      .icon-mini {
        position: relative;
        font-size: 20px;
        color: #f80000;
        top: 0;
        left: 0;
      }
   }
  }
  @keyframes rotate {
    0% {
      transform: rotate(0)
    } 
    100% {
      transform: rotate(360deg)
    }
  }
      
}
</style>

